#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QScreen>
#include <QLabel>
#include <QTimer>
#include <QPixmap>
#include <QList>
#include <QDesktopWidget>
#include <QLocalServer>
#include <QLocalSocket>
#include <QJsonDocument>
#include <QJsonObject>

/**
 * @class MainWindow
 * @brief 主窗口类，继承自 QMainWindow，用于实现屏幕投屏和白板显示功能。
 * 
 * 该类处理与屏幕管理、套接字通信、屏幕捕获和用户界面初始化相关的操作。
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数，初始化主窗口。
     * 
     * @param screenName 要移动到的屏幕名称，默认为空字符串。
     * @param parent 父窗口指针，默认为 nullptr。
     */
    MainWindow(const QString &screenName = QString(), QWidget *parent = nullptr);
    /**
     * @brief 析构函数，清理资源。
     */
    ~MainWindow();
    
private slots:
    /**
     * @brief 处理新的套接字连接。
     * 
     * 当有新的客户端连接到本地套接字服务器时，此槽函数会被调用。
     * 它会处理新连接的相关逻辑，例如设置当前活动的套接字连接，
     * 并连接套接字的 readyRead 信号到 handleSocketData 槽函数，以处理接收到的数据。
     */
    void handleNewConnection();
    
    /**
     * @brief 处理套接字接收到的数据。
     * 
     * 当套接字有新的数据可读时，此槽函数会被调用。
     * 它会读取套接字中的数据，并将其解析为 JSON 对象，
     * 然后调用 handleCommand 函数来处理接收到的命令。
     */
    void handleSocketData();
    /**
     * @brief 3 秒后开始屏幕捕获。
     * 
     * 此函数会启动一个单次触发的定时器，在 3 秒后触发 startScreenCapture 函数，
     * 从而开始周期性的屏幕捕获操作。
     */
    void startScreenCapture();
    
    /**
     * @brief 周期性地捕获屏幕。
     * 
     * 此槽函数会被定时器周期性地调用，用于捕获屏幕内容，
     * 并将捕获的屏幕截图显示在中央标签上。
     */
    // Slot to capture screen periodically
    void captureScreen();

private:
    /**
     * @brief 获取所有屏幕的信息。
     * 
     * 此函数会获取系统中所有可用屏幕的信息，
     * 并记录最低和最高索引的屏幕，以便后续使用。
     */
    // Get information about all screens
    void getScreenInfo();
    
    /**
     * @brief 移动到索引最高的屏幕并全屏显示。
     * 
     * 此函数会将主窗口移动到系统中索引最高的屏幕，
     * 并将窗口设置为全屏显示。
     */
    // Move to the screen with the highest index and go fullscreen
    void moveToHighestIndexScreen();
    
    /**
     * @brief 根据屏幕名称移动到指定屏幕并全屏显示。
     * 
     * 此函数会尝试在可用屏幕列表中查找指定名称的屏幕，
     * 如果找到则将主窗口移动到该屏幕并设置为全屏显示。
     */
    bool moveToScreenByName(const QString &screenName);
    
    // Show error message for invalid screen name
    /**
     * @brief 显示无效屏幕名称的错误信息。
     * 
     * 当用户提供的屏幕名称无效时，调用此函数显示错误信息。
     * 该函数会将错误信息显示在界面上，提示用户输入的屏幕名称不存在。
     * 
     * @param screenName 无效的屏幕名称。
     */
    void showInvalidScreenNameError(const QString &screenName);
    
    /**
     * @brief 初始化 Unix Domain Socket 服务器。
     * 
     * 此函数用于设置并启动 Unix Domain Socket 服务器，
     * 为接收来自客户端的连接和数据做准备。
     */
    // Initialize the Unix Domain Socket server
    void initializeSocketServer();
    
    /**
     * @brief 处理从套接字接收到的命令。
     * 
     * 当通过套接字接收到命令时，调用此函数进行解析和处理。
     * 它会根据命令的内容执行相应的操作。
     * 
     * @param command 接收到的命令，以 JSON 对象的形式表示。
     */
    // Handle commands received from the socket
    void handleCommand(const QJsonObject &command);
    
    /**
     * @brief 开始投屏指定屏幕。
     * 
     * 此函数用于启动对指定名称屏幕的投屏操作。
     * 它会设置相应的状态变量，并开始屏幕捕获和显示。
     * 
     * @param screenName 要投屏的屏幕名称。
     */
    // Start casting a specific screen
    void startCast(const QString &screenName);
    
    /**
     * @brief 停止投屏并恢复白板显示。
     * 
     * 此函数用于停止当前的投屏操作，
     * 并将界面恢复到显示 "智林白板" 的初始状态。
     */
    // Stop casting and restore the whiteboard
    void stopCast();
    
    /**
     * @brief 用 "智林白板" 文本初始化用户界面。
     * 
     * 此函数用于设置主窗口的初始界面，
     * 在中央标签上显示 "智林白板" 文本，并进行相关的样式设置。
     */
    // Initialize the UI with the "智林白板" text
    void initializeUI();
    
    /**
     * Unix Domain Socket 服务器对象指针，
     * 用于监听客户端的连接请求。
     */
    // Unix Domain Socket server
    QLocalServer *m_socketServer;
    
    /**
     * 当前活动的套接字连接对象指针，
     * 用于与客户端进行数据通信。
     */
    // Current active socket connection
    QLocalSocket *m_currentSocket;
    
    /**
     * 标志位，指示当前是否正在进行屏幕投屏。
     * true 表示正在投屏，false 表示未投屏。
     */
    // Flag to indicate if we're currently casting a screen
    bool m_isCasting;
    
    /**
     * 当前正在投屏的屏幕的索引。
     * -1 表示没有正在投屏的屏幕。
     */
    // Index of the screen currently being cast
    int m_castingScreenIndex;
    
    /**
     * 当前正在投屏的屏幕的名称。
     * 空字符串表示没有正在投屏的屏幕。
     */
    // Name of the screen currently being cast
    QString m_castingScreenName;
    /**
     * 中央标签对象指针，用于显示 "智林白板" 文本或捕获的屏幕截图。
     */
    // Label to display the "智林白板" text or captured screen
    QLabel *m_centralLabel;
    
    /**
     * 定时器对象指针，用于在 3 秒后启动屏幕捕获操作。
     */
    // Timer for starting screen capture after 3 seconds
    QTimer *m_startCaptureTimer;
    
    /**
     * 定时器对象指针，用于周期性地进行屏幕捕获操作。
     */
    // Timer for periodic screen capture
    QTimer *m_captureTimer;
    
    /**
     * 可用屏幕的列表，存储了系统中所有可用屏幕的指针。
     */
    // List of available screens
    QList<QScreen*> m_screens;
    
    /**
     * 索引最低的屏幕的索引，用于屏幕捕获操作。
     */
    // Index of the screen with the lowest index (for capture)
    int m_lowestScreenIndex;
    
    /**
     * 索引最高的屏幕的索引，用于显示操作。
     */
    // Index of the screen with the highest index (for display)
    int m_highestScreenIndex;
};

#endif // MAINWINDOW_H

